<?php

namespace app\common\service\qrcode;


use app\common\service\ApiService;
use ba\Exception;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\PngWriter;

class QrcodeService extends ApiService
{
    private $defaultOptions = [
        'width' => 300,
        'height' => 300,
        'margin' => 10,
        'errorCorrection' => 'high',
        'foregroundColor' => [0, 0, 0], // 黑色
        'backgroundColor' => [255, 255, 255] // 白色
    ];

    public function generate($params = [], $options = [])
    {
        try {
            // 合并选项
            $options = array_merge($this->defaultOptions, $options);

            // 验证参数
            $this->validateOptions($options);

            // 生成查询字符串
            $queryString = $this->buildQueryString($params);

            // 生成二维码
            $builder = new Builder(
                writer: new PngWriter(),
                writerOptions: [],
                validateResult: false,
                data: $queryString,
                encoding: new Encoding('UTF-8'),
                errorCorrectionLevel: ErrorCorrectionLevel::High,
                size: min($options['width'], $options['height']),
                margin: $options['margin'],
                roundBlockSizeMode: RoundBlockSizeMode::Margin,
                foregroundColor: new Color(
                    $options['foregroundColor'][0],
                    $options['foregroundColor'][1],
                    $options['foregroundColor'][2]
                ),
                backgroundColor: new Color(
                    $options['backgroundColor'][0],
                    $options['backgroundColor'][1],
                    $options['backgroundColor'][2]
                )
            );

            $result = $builder->build();
            // 调整尺寸
            $finalImage = $this->resizeImage(
                $result->getString(),
                $options['width'],
                $options['height']
            );

            // 转换为Base64
            $base64 = base64_encode($finalImage);
            return "data:image/png;base64," . $base64;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 调整图片尺寸
     */
    private function resizeImage($imageData, $width, $height)
    {
        $srcImage = imagecreatefromstring($imageData);
        $srcWidth = imagesx($srcImage);
        $srcHeight = imagesy($srcImage);

        // 创建目标图片
        $dstImage = imagecreatetruecolor($width, $height);

        // 填充背景色
        $white = imagecolorallocate($dstImage, 255, 255, 255);
        imagefill($dstImage, 0, 0, $white);

        // 计算居中位置
        $x = ($width - $srcWidth) / 2;
        $y = ($height - $srcHeight) / 2;

        // 复制并调整尺寸
        imagecopy($dstImage, $srcImage, $x, $y, 0, 0, $srcWidth, $srcHeight);

        // 输出到缓冲区
        ob_start();
        imagepng($dstImage);
        $result = ob_get_clean();

        // 释放内存
        imagedestroy($srcImage);
        imagedestroy($dstImage);

        return $result;
    }

    /**
     * 验证选项
     */
    private function validateOptions($options)
    {
        if ($options['width'] <= 0 || $options['height'] <= 0) {
            throw new Exception('宽度和高度必须大于0');
        }

        if ($options['width'] > 5000 || $options['height'] > 5000) {
            throw new Exception('宽度和高度不能超过5000像素');
        }
    }

    /**
     * 构建查询字符串
     */
    private function buildQueryString($params)
    {
        if (empty($params)) {
            throw new Exception('参数不能为空');
        }
        if (is_array($params)) {
            $params = http_build_query($params);
        }
        return $params;
    }
}
